"""
filename: script_parser.py

Parse any text file and try to exec the commands

a script file looks like:

load 第一段.m4a -top
load bgm1.mp3 -bgm
chkvars
compose -top -bgm -merge
save -merge 测试
"""
from .audio_core import *
from .qt_signal import SIGNAL
import re

def debug(text):
    print(text)
    SIGNAL.text_print.emit(str(text))


SPACES = re.compile(r' {2,}')
VARS = dict()
COMMANDS = {
    'load': {'argc': 2,
             'func': robust_load_audio,
             'args_pos': [1],
             'return_to': 2,
             'help': 'load <FILE NAME> <VAR: NAME>'},
    'compose': {'argc': 3,
                'func': make_audio_with_bgm,
                'args_pos': [1, 2],
                'return_to': 3,
                'help': 'compose <VAR:TOP MUSIC> <VAR:BGM MUSIC> <VAR:SAVE TO>'},
    'save': {'argc': 2,
             'func': save_to_file,
             'args_pos': [1, 2],
             'return_to': -1,
             'help': 'save <VAR: NAME> <FILE NAME>'},
    'chkvars': {'argc': 0,
                'help': 'builtin command to check all variables'},
}


def parse_and_exec(text):
    """Parse the file and try to exec the commands

    Args:
        file (str): the file to parse
    """
    ln = 0
    for line in text.split('\n'):
        ln += 1
        if len(line) < 2 or line.startswith('#'):
            continue
        line0 = SPACES.sub('', line).replace('\n', '')
        # seperate all args
        args = line0.split(' ')
        if not args[0] in COMMANDS:
            debug(f'Unknown command at line {ln}: {args[0]}')
            break
        # check command count
        if line0.count(' ') != COMMANDS[args[0]]['argc']:
            debug(f'Illegal call of keyword {args[0]} at line {ln}:')
            debug(COMMANDS[args[0]]['help'])
            break
        # exec commands
        cmd = args[0]
        if cmd == 'chkvars':
            debug(VARS)
        else:
            # parse cmd
            return_pos = COMMANDS[args[0]]['return_to']
            arg_pos = COMMANDS[args[0]]['args_pos']
            arg_list = []
            for i in arg_pos:
                # is a VAR
                if args[i].startswith('-'):
                    arg_list.append(VARS[args[i]])
                # is literal
                else:
                    arg_list.append(args[i])
            result = COMMANDS[args[0]]['func'](*arg_list)
            if return_pos != -1:
                VARS[args[return_pos]] = result

if __name__ == '__main__':
    
    parse_and_exec(open('test.boat').read())
